home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 February: Tool Chest / Dev.CD Feb 00 TC.toast / pc / what's new? / sample code / graphics 3d / setupgl / setupgl.c < prev    next >
Encoding:
Text File  |  1999-12-18  |  21.2 KB  |  651 lines

  1. /*
  2.     File:        SetupGL.c
  3.  
  4.     Contains:    Functions to enable building and destorying a GL full screen or windowed context
  5.  
  6.     Written by:    Geoff Stahl (ggs)
  7.  
  8.     Copyright:    Copyright © 1999 Apple Computer, Inc., All Rights Reserved
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <10>   12/18/99    ggs     Added Windowed creation
  13.             <9>    11/28/99    ggs     Split out DSp and error handling.  Added texture memory
  14.                                     considerations, assume VRAM is required if other than zero
  15.          <8>    11/14/99    ggs     Fix source server copy
  16.          <7>    11/13/99    ggs     fixed default pixel depth (0) condition that was causing failures
  17.          <6>    11/13/99    ggs     added custom fade code
  18.          <5>    11/13/99    ggs     Reset for Quake 3 use
  19.          <4>    11/12/99    ggs     re-add
  20.          <3>    11/12/99    ggs     added support for frequency retrieval, fixed display number
  21.                                     output to be correct if display number input was -1
  22.          <2>    11/12/99    ggs     1.0 functionality
  23.          <1>    11/11/99    ggs     Initial Add
  24.  
  25.     Disclaimer:    IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
  26.                 ("Apple") in consideration of your agreement to the following terms, and your
  27.                 use, installation, modification or redistribution of this Apple software
  28.                 constitutes acceptance of these terms.  If you do not agree with these terms,
  29.                 please do not use, install, modify or redistribute this Apple software.
  30.  
  31.                 In consideration of your agreement to abide by the following terms, and subject
  32.                 to these terms, Apple grants you a personal, non-exclusive license, under Apple’s
  33.                 copyrights in this original Apple software (the "Apple Software"), to use,
  34.                 reproduce, modify and redistribute the Apple Software, with or without
  35.                 modifications, in source and/or binary forms; provided that if you redistribute
  36.                 the Apple Software in its entirety and without modifications, you must retain
  37.                 this notice and the following text and disclaimers in all such redistributions of
  38.                 the Apple Software.  Neither the name, trademarks, service marks or logos of
  39.                 Apple Computer, Inc. may be used to endorse or promote products derived from the
  40.                 Apple Software without specific prior written permission from Apple.  Except as
  41.                 expressly stated in this notice, no other rights or licenses, express or implied,
  42.                 are granted by Apple herein, including but not limited to any patent rights that
  43.                 may be infringed by your derivative works or by other works in which the Apple
  44.                 Software may be incorporated.
  45.  
  46.                 The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
  47.                 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
  48.                 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  49.                 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
  50.                 COMBINATION WITH YOUR PRODUCTS.
  51.  
  52.                 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
  53.                 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  54.                 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  55.                 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
  56.                 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
  57.                 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
  58.                 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59. */
  60.  
  61.  
  62. // system includes ----------------------------------------------------------
  63.  
  64.  
  65. // project includes ---------------------------------------------------------
  66.  
  67. #include "Error Handler.h"
  68. #include "SetupDSp.h"
  69. #include "SetupGL.h"
  70.  
  71.  
  72. // globals (internal/private) -----------------------------------------------
  73.  
  74. const RGBColor    rgbBlack    = { 0x0000, 0x0000, 0x0000 };
  75.  
  76.  
  77. // prototypes (internal/private) --------------------------------------------
  78.  
  79. Boolean CheckRenderer (GDHandle hGD, long *VRAM, long *textureRAM, GLint* pDepthSizeSupport, Boolean fAccelMust);
  80. Boolean CheckWindowExtents (GDHandle hGD, short width, short height);
  81. void DumpCurrent (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext, pstructGLInfo pcontextInfo);
  82.  
  83. GLenum BuildGLContext (AGLDrawable* paglDraw, AGLContext* paglContext, GDHandle hGD, pstructGLInfo pcontextInfo);
  84. OSStatus BuildDrawable (AGLDrawable* paglDraw, GDHandle hGD, pstructGLInfo pcontextInfo);
  85. OSStatus BuildDSpContext (DSpContextReference* pdspContext, GDHandle hGD, GLint depthSizeSupport, pstructGLInfo pcontextInfo);
  86. OSStatus BuildGLonDevice (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext, 
  87.                             GDHandle hGD, pstructGLInfo pcontextInfo);
  88.                             
  89.  
  90. // functions (internal/private) ---------------------------------------------
  91.  
  92. // CheckRenderer
  93.  
  94. // looks at renderer attributes it has at least the VRAM is accelerated
  95.  
  96. // Inputs:     hGD: GDHandle to device to look at
  97. //            pVRAM: pointer to VRAM in bytes required; out is actual VRAM if a renderer was found, otherwise it is the input parameter
  98. //            pTextureRAM:  pointer to texture RAM in bytes required; out is same (implementation assume VRAM returned by card is total so we add texture and VRAM)
  99. //            fAccelMust: do we check fro acceleration
  100.  
  101. // Returns: true is renderer for the requested device complies, false otherwise; depth buffer bit depths supported
  102.  
  103. Boolean CheckRenderer (GDHandle hGD, long* pVRAM, long* pTextureRAM, GLint* pDepthSizeSupport, Boolean fAccelMust)
  104. {
  105.     AGLRendererInfo info, head_info;
  106.     GLint inum;
  107.     GLint dAccel = 0;
  108.     GLint dVRAM = 0;
  109.     
  110.     head_info = aglQueryRendererInfo(&hGD, 1);
  111.     aglReportError ();
  112.     if(!head_info)
  113.     {
  114.         ReportError ("aglQueryRendererInfo error");
  115.         return false;
  116.     }
  117.     else
  118.     {
  119.         info = head_info;
  120.         inum = 0;
  121.         while (info)
  122.         {    
  123.             aglDescribeRenderer(info, AGL_ACCELERATED, &dAccel);
  124.             aglReportError ();
  125.             if (!fAccelMust || dAccel)
  126.             {
  127.                 aglDescribeRenderer(info, AGL_VIDEO_MEMORY, &dVRAM);    // we assume that VRAM returned is total thus add texture and VRAM required
  128.                 aglReportError ();
  129.                 if (dVRAM >= (*pVRAM + *pTextureRAM))
  130.                 {
  131.                     aglDescribeRenderer(info, AGL_DEPTH_MODES, pDepthSizeSupport);    // which depth buffer modes are supported
  132.                     aglReportError ();
  133.                     aglDestroyRendererInfo(head_info);
  134.                     *pVRAM = dVRAM; // return actual VRAM
  135.                     
  136.                     return true;
  137.                 }
  138.             }
  139.             info = aglNextRendererInfo(info);
  140.             aglReportError ();
  141.             inum++;
  142.         }
  143.     }
  144.     aglDestroyRendererInfo(head_info);
  145.     // VRAM will remain to same as it did when sent in
  146.     return false;
  147. }
  148.  
  149. //-----------------------------------------------------------------------------------------------------------------------
  150.  
  151. // CheckWindowExtents
  152.  
  153. // looks at renderer attributes it has at least the VRAM is accelerated
  154.  
  155. // Inputs:     hGD: GDHandle to device to look at
  156. //            width/height: requested width and height of window
  157.  
  158. // Returns: true is renderer for the requested device complies, false otherwise
  159.  
  160. Boolean CheckWindowExtents (GDHandle hGD, short width, short height)
  161. {
  162.     Rect strucRect, rectWin = {0, 0, 1, 1};
  163.     short deviceHeight = (**hGD).gdRect.bottom - (**hGD).gdRect.top - GetMBarHeight ();    
  164.     short deviceWidth = (**hGD).gdRect.right - (**hGD).gdRect.left;
  165.     short windowWidthExtra, windowHeightExtra;
  166.     // build window (not visible)
  167.     WindowPtr pWindow = NewCWindow (NULL, &rectWin, "\p", true, kWindowDocumentProc, (WindowPtr)-1, 0, 0);
  168.     
  169.     strucRect = (**(((WindowPeek)pWindow)->strucRgn)).rgnBBox;
  170.     windowWidthExtra = (strucRect.right - strucRect.left) - 1;
  171.     windowHeightExtra = (strucRect.bottom - strucRect.top) - 1;
  172.     if ((width + windowWidthExtra <= deviceWidth) &&
  173.         (height + windowHeightExtra <= deviceHeight))
  174.     {
  175.         return true;
  176.     }
  177.     return false;
  178. }
  179.  
  180. // --------------------------------------------------------------------------
  181.  
  182. // DumpCurrent
  183.  
  184. // Kills currently allocated context
  185. // does not care about being pretty (assumes display is liekly faded)
  186.  
  187. // Inputs:     paglDraw, paglContext, pdspContext: things to be destroyed
  188.  
  189. void DumpCurrent (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext, pstructGLInfo pcontextInfo)
  190. {
  191.     if (*paglContext)
  192.     {
  193.         aglSetCurrentContext (NULL);
  194.         aglSetDrawable (*paglContext, NULL);
  195.         aglDestroyContext (*paglContext);
  196.         *paglContext = NULL;
  197.     }
  198.     
  199.     if (pcontextInfo->fmt)
  200.         aglDestroyPixelFormat (pcontextInfo->fmt); // pixel format is no longer needed
  201.     pcontextInfo->fmt = 0;
  202.  
  203.     if (*paglDraw)
  204.         DisposeWindow ((WindowPtr)*paglDraw);
  205.     *paglDraw = NULL;
  206.  
  207.     DestroyDSpContext (pdspContext);
  208. }
  209.  
  210. #pragma mark -
  211. // --------------------------------------------------------------------------
  212.  
  213. // BuildGLContext
  214.  
  215. // Builds OpenGL context
  216.  
  217. // Inputs:     hGD: GDHandle to device to look at
  218. //            pcontextInfo: request and requirements for cotext and drawable
  219.  
  220. // Outputs: paglContext as allocated
  221. //            pcontextInfo:  allocated parameters
  222.  
  223. // if fail to allocate: paglContext will be NULL
  224. // if error: will return error paglContext will be NULL
  225.  
  226. GLenum BuildGLContext (AGLDrawable* paglDraw, AGLContext* paglContext, GDHandle hGD, pstructGLInfo pcontextInfo)
  227. {
  228.     GLenum            err = AGL_NO_ERROR;
  229.  
  230.     if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) // check for existance of OpenGL
  231.     {
  232.         ReportError ("OpenGL not installed");
  233.         return NULL;
  234.     }    
  235.  
  236.     pcontextInfo->fmt = aglChoosePixelFormat (&hGD, 1, pcontextInfo->aglAttributes); // get an appropriate pixel format
  237.     aglReportError ();
  238.     if (NULL == pcontextInfo->fmt) 
  239.     {
  240.         ReportError("Could not find valid pixel format");
  241.         return NULL;
  242.     }
  243.  
  244.     *paglContext = aglCreateContext (pcontextInfo->fmt, NULL);                // Create an AGL context
  245.     aglReportError ();
  246.     if (NULL == *paglContext) 
  247.     {
  248.         ReportError ("Could not create context");
  249.         return NULL;
  250.     }
  251.     
  252.     // build window as late as possible
  253.     err = BuildDrawable (paglDraw, hGD, pcontextInfo);
  254.     if (err != noErr)
  255.     {
  256.         ReportError ("Could not build drawable");
  257.         return err;
  258.     }
  259.  
  260.     if (!aglSetDrawable (*paglContext, *paglDraw))                // attach the CGrafPtr to the context
  261.         return aglReportError ();
  262.     
  263.     if(!aglSetCurrentContext (*paglContext))                    // make the context the current context
  264.         return aglReportError ();
  265.  
  266.     
  267.     return err;
  268. }
  269.  
  270. // --------------------------------------------------------------------------
  271.  
  272. // BuildDrawable
  273.  
  274. // Builds window to be used as drawable
  275.  
  276. // Inputs:     hGD: GDHandle to device to look at
  277. //            pcontextInfo: request and requirements for cotext and drawable
  278.  
  279. // Outputs: paglDraw as allocated
  280. //            pcontextInfo:  allocated parameters
  281.  
  282. // if fail to allocate: paglDraw will be NULL
  283. // if error: will return error paglDraw will be NULL
  284.  
  285. OSStatus BuildDrawable (AGLDrawable* paglDraw, GDHandle hGD, pstructGLInfo pcontextInfo)
  286. {
  287.     Rect rectWin;
  288.     RGBColor rgbSave;
  289.     GrafPtr pGrafSave;
  290.     OSStatus err = noErr;
  291.     
  292.     // center window in our context's gdevice
  293.     rectWin.top  = (**hGD).gdRect.top + ((**hGD).gdRect.bottom - (**hGD).gdRect.top) / 2; // v center
  294.     rectWin.top  -= pcontextInfo->height / 2;
  295.     rectWin.left  = (**hGD).gdRect.left + ((**hGD).gdRect.right - (**hGD).gdRect.left) / 2;    // h center
  296.     rectWin.left  -= pcontextInfo->width / 2;
  297.     rectWin.right = rectWin.left + pcontextInfo->width;
  298.     rectWin.bottom = rectWin.top + pcontextInfo->height;
  299.     
  300.     if (pcontextInfo->fFullscreen)
  301.         *paglDraw = (AGLDrawable) NewCWindow (NULL, &rectWin, "\p", 0, plainDBox, (WindowPtr)-1, 0, 0);
  302.     else
  303.         *paglDraw = (AGLDrawable) NewCWindow (NULL, &rectWin, "\p", 0, kWindowDocumentProc, (WindowPtr)-1, 0, 0);
  304.  
  305.     ShowWindow ((GrafPtr)*paglDraw);
  306.     GetPort (&pGrafSave);
  307.     SetPort ((GrafPtr)*paglDraw);
  308.     GetForeColor (&rgbSave);
  309.     RGBForeColor (&rgbBlack);
  310.     PaintRect (&(*paglDraw)->portRect);
  311.     RGBForeColor (&rgbSave); // ensure color is reset for proper blitting
  312.     SetPort (pGrafSave);
  313.     return err;
  314. }
  315.  
  316. // --------------------------------------------------------------------------
  317.  
  318. // BuildGLonDevice
  319.  
  320. // Takes device single device and tries to build on it
  321.  
  322. // Inputs:     hGD: GDHandle to device to look at
  323. //            *pcontextInfo: request and requirements for cotext and drawable
  324.  
  325. // Outputs: *paglDraw, *paglContext and *pdspContext as allocated
  326. //            *pcontextInfo:  allocated parameters
  327.  
  328. // if fail to allocate: paglDraw, paglContext and pdspContext will be NULL
  329. // if error: will return error and paglDraw, paglContext and pdspContext will be NULL
  330.  
  331. OSStatus BuildGLonDevice (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext, 
  332.                             GDHandle hGD, pstructGLInfo pcontextInfo)
  333. {
  334.     GLint depthSizeSupport = 0;
  335.     OSStatus err = noErr;
  336.     Boolean fCheckRenderer = false;
  337.  
  338.     if (pcontextInfo->fFullscreen)
  339.     {
  340.         // if we are in 16 or 32 bit mode already, we can check the renderer now (we will double check later)
  341.         if (16 <= (**(**hGD).gdPMap).pixelSize)
  342.         {
  343.             // check for VRAM and accelerated
  344.             if (!CheckRenderer (hGD, &(pcontextInfo->VRAM), &(pcontextInfo->textureRAM), &depthSizeSupport, pcontextInfo->fAcceleratedMust))
  345.             {
  346.                 ReportError ("Renderer check failed");
  347.                 return err;
  348.             }
  349.             else
  350.                 fCheckRenderer = true;
  351.         }
  352.         
  353.         err = BuildDSpContext (pdspContext, hGD, depthSizeSupport, pcontextInfo);
  354.         if ((err != noErr) || (*pdspContext == NULL))
  355.         {
  356.             if (err != noErr)
  357.                 ReportErrorNum ("BuildDSpContext failed with error:", err);
  358.             else
  359.                 ReportError ("Could not build DrawSprocket context");
  360.             return err;
  361.         }
  362.     }
  363.     else
  364.     {
  365.         if (pcontextInfo->pixelDepth == 0)    // default
  366.         {
  367.             pcontextInfo->pixelDepth = (**(**hGD).gdPMap).pixelSize;
  368.             if (16 > pcontextInfo->pixelDepth)
  369.                 pcontextInfo->pixelDepth = 16;
  370.         }
  371.         if (pcontextInfo->fDepthMust && (pcontextInfo->pixelDepth != (**(**hGD).gdPMap).pixelSize))    // device depth must match and does not
  372.         {
  373.             ReportError ("Pixel Depth does not match device in windowed mode.");
  374.             return err;
  375.         }
  376.         if (!CheckWindowExtents (hGD, pcontextInfo->width, pcontextInfo->height))
  377.         {
  378.             ReportError ("Window will not fit on device in windowed mode.");
  379.             return err;
  380.         }
  381.     }
  382.     
  383.     // if we have not already checked the renderer, check for VRAM and accelerated
  384.     if (!fCheckRenderer)
  385.         if (!CheckRenderer (hGD, &(pcontextInfo->VRAM), &(pcontextInfo->textureRAM), &depthSizeSupport, pcontextInfo->fAcceleratedMust))
  386.         {
  387.             ReportError ("Renderer check failed");
  388.             return err;
  389.         }
  390.     
  391.     // do agl
  392.     err = BuildGLContext (paglDraw, paglContext, hGD, pcontextInfo);
  393.     
  394.     // set output parameters
  395.     
  396.     return err;
  397. }
  398.  
  399. #pragma mark -
  400. // functions (public) -------------------------------------------------------
  401.  
  402. // BuildGL
  403.  
  404. // Takes device and geometry request and tries to build best context and drawable
  405. // if device does not work will walk down devices looking for first one that satisfies requirments
  406.  
  407. // Inputs:     *pnumDevice: 0 any device, # attempt that device first, then any device
  408. //            *pcontextInfo: request and requirements for cotext and drawable
  409.  
  410. // Outputs: *paglDraw, *paglContext and *pdspContext as allocated
  411. //            *pnumDevice to device number in list that was used 
  412. //            *pcontextInfo:  allocated parameters
  413.  
  414. // if fail to allocate: paglDraw, paglContext and pdspContext will be NULL
  415. // if error: will return error and paglDraw, paglContext and pdspContext will be NULL
  416.  
  417. OSStatus BuildGL (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext, 
  418.                   short* pnumDevice, pstructGLInfo pcontextInfo)
  419. {
  420.     GDHandle hGD = NULL;
  421.     OSStatus err = noErr;
  422.     structGLInfo contextInfoSave;
  423.     
  424.     // clear
  425.     *paglDraw = 0;
  426.     *paglContext = 0;
  427.     *pdspContext = 0;
  428.     contextInfoSave = *pcontextInfo; // save info to reset on failures
  429.     
  430.     if (pcontextInfo->fFullscreen)
  431.     {
  432.         err = StartDSp ();
  433.         if (gDSpStarted)
  434.             gNeedFade = true;
  435.         else
  436.             return err;
  437.     }
  438.     
  439.     //find main device
  440.     if (*pnumDevice == -1)
  441.     {
  442.         GDHandle hDevice; // check number of screens
  443.         hGD = GetMainDevice ();
  444.         if (NULL != hGD)
  445.         {
  446.             err = BuildGLonDevice (paglDraw, paglContext, pdspContext, hGD, pcontextInfo);
  447.             
  448.             // find device number
  449.             *pnumDevice = 0;
  450.             hDevice = DMGetFirstScreenDevice (true);
  451.             do
  452.             {
  453.                 if (hDevice == hGD)
  454.                     break;
  455.                 hDevice = DMGetNextScreenDevice (hDevice, true);
  456.                 (*pnumDevice)++;
  457.             }
  458.             while (hDevice);
  459.             if (!hDevice)
  460.                 ReportError ("main device match not found");
  461.         }
  462.         else
  463.             ReportError ("Cannot get main device");
  464.     }
  465.  
  466.     if ((err != noErr) || (*paglDraw == 0) || (*paglContext == 0))
  467.     {
  468.         *pcontextInfo = contextInfoSave; // restore info
  469.         //find target device and check this first is one exists
  470.         if (*pnumDevice)
  471.         {
  472.             short i;
  473.             hGD = DMGetFirstScreenDevice (true);
  474.             for (i = 0; i < *pnumDevice; i++)
  475.             {
  476.                 GDHandle hGDNext = DMGetNextScreenDevice (hGD, true);
  477.                 if (NULL == hGDNext) // ensure we did not run out of devices
  478.                     break; // if no more devices drop out
  479.                 else
  480.                     hGD = hGDNext; // otherwise continue
  481.             }
  482.             *pnumDevice = i; // record device we actually got
  483.             err = BuildGLonDevice (paglDraw, paglContext, pdspContext, hGD, pcontextInfo);
  484.         }
  485.     }
  486.     
  487.     // while we have not allocated a context or there were errors
  488.     if ((err != noErr) || (*paglDraw == 0) || (*paglContext == 0))
  489.     {
  490.         DumpCurrent (paglDraw, paglContext, pdspContext, pcontextInfo); // dump what ever partial solution we might have
  491.         *pcontextInfo = contextInfoSave; // restore info
  492.         // now look through the devices in order
  493.         hGD = DMGetFirstScreenDevice (true);    
  494.         *pnumDevice = -1;
  495.         do 
  496.         {
  497.             (*pnumDevice)++;
  498.             err = BuildGLonDevice (paglDraw, paglContext, pdspContext, hGD, pcontextInfo);
  499.             if ((err != noErr) || (*paglDraw == 0) || (*paglContext == 0))    // reset hGD only if we are not done
  500.             {
  501.                 hGD = DMGetNextScreenDevice (hGD, true);
  502.                 DumpCurrent (paglDraw, paglContext, pdspContext, pcontextInfo); // dump what ever partial solution we might have
  503.                 *pcontextInfo = contextInfoSave; // restore info
  504.             }
  505.         }
  506.         while (((err != noErr) || (*paglDraw == 0) || (*paglContext == 0)) && hGD);
  507.     }
  508.     
  509.     if ((gDSpStarted) && (pcontextInfo->fFullscreen))
  510.     {
  511.         DSpReportError (DSpContext_CustomFadeGammaIn (NULL, NULL, 5));
  512.     }
  513.  
  514.     return err;
  515. }
  516.  
  517. // --------------------------------------------------------------------------
  518.  
  519. // DestroyGL
  520.  
  521. // Destroys drawable and context
  522. // Ouputs: *paglDraw, *paglContext and *pdspContext should be 0 on exit
  523.  
  524. OSStatus DestroyGL (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext, pstructGLInfo pcontextInfo)
  525. {
  526.     if (gDSpStarted)
  527.     {
  528.         DSpReportError (DSpContext_CustomFadeGammaOut (NULL, NULL, 5));
  529.     }
  530.     
  531.     DumpCurrent (paglDraw, paglContext, pdspContext, pcontextInfo);
  532.  
  533.     ShutdownDSp ();
  534.         
  535.     return noErr;
  536. }
  537.  
  538. // --------------------------------------------------------------------------
  539.  
  540. // BuildGLFromWindow
  541.  
  542. // same as above except that it takes a window as input and attempts to build requested cotext on that
  543.  
  544. OSStatus BuildGLFromWindow (AGLDrawable aglDraw, AGLContext* paglContext, pstructGLWindowInfo pcontextInfo)
  545. {
  546.     GDHandle hGD = NULL;
  547.     OSStatus err = noErr;
  548.     structGLWindowInfo contextInfoSave;
  549.     GLenum glerr = AGL_NO_ERROR;
  550.     GLint depthSizeSupport = 0;
  551.     
  552.     // clear
  553.     *paglContext = 0;
  554.     contextInfoSave = *pcontextInfo; // save info to reset on failures
  555.     
  556.     if (!CheckRenderer (hGD, &(pcontextInfo->VRAM), &(pcontextInfo->textureRAM), &depthSizeSupport, pcontextInfo->fAcceleratedMust))
  557.     {
  558.         ReportError ("Renderer check failed");
  559.         *pcontextInfo = contextInfoSave; // restore info
  560.         return err;
  561.     }
  562.     
  563.     // do agl
  564.     if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) // check for existance of OpenGL
  565.     {
  566.         ReportError ("OpenGL not installed");
  567.         *pcontextInfo = contextInfoSave; // restore info
  568.         return NULL;
  569.     }    
  570.  
  571.     pcontextInfo->fmt = aglChoosePixelFormat (NULL, 0, pcontextInfo->aglAttributes); // get an appropriate pixel format
  572.     aglReportError ();
  573.     if (NULL == pcontextInfo->fmt) 
  574.     {
  575.         ReportError("Could not find valid pixel format");
  576.         *pcontextInfo = contextInfoSave; // restore info
  577.         return NULL;
  578.     }
  579.  
  580.     *paglContext = aglCreateContext (pcontextInfo->fmt, NULL); // Create an AGL context
  581.     aglReportError ();
  582.     if (NULL == *paglContext) 
  583.     {
  584.         ReportError ("Could not create context");
  585.         *pcontextInfo = contextInfoSave; // restore info
  586.         return NULL;
  587.     }
  588.     
  589.     if (!aglSetDrawable (*paglContext, aglDraw)) // attach the CGrafPtr to the context
  590.     {
  591.         *pcontextInfo = contextInfoSave; // restore info
  592.         return aglReportError ();
  593.     }
  594.     
  595.     if(!aglSetCurrentContext (*paglContext)) // make the context the current context
  596.     {
  597.         *pcontextInfo = contextInfoSave; // restore info
  598.         return aglReportError ();
  599.     }
  600.  
  601.     return err;
  602. }
  603.  
  604. // --------------------------------------------------------------------------
  605.  
  606. // DestroyGLFromWindow
  607.  
  608. // same as above but destorys a context that was associated with an existing window, window is left intacted
  609.  
  610. OSStatus DestroyGLFromWindow (AGLContext* paglContext, pstructGLWindowInfo pcontextInfo)
  611. {
  612.     if (*paglContext)
  613.     {
  614.         aglSetCurrentContext (NULL);
  615.         aglSetDrawable (*paglContext, NULL);
  616.         aglDestroyContext (*paglContext);
  617.         *paglContext = NULL;
  618.     }
  619.     
  620.     if (pcontextInfo->fmt)
  621.         aglDestroyPixelFormat (pcontextInfo->fmt); // pixel format is no longer needed
  622.     pcontextInfo->fmt = 0;
  623.     
  624.     return noErr;
  625. }
  626.  
  627. //-----------------------------------------------------------------------------------------------------------------------
  628.  
  629. // PauseGL
  630.  
  631. // Pauses gl to allow toolbox drawing
  632.  
  633. OSStatus PauseGL (AGLContext aglContext)
  634. {
  635.     glFinish (); // must do this to ensure the queue is complete
  636.     aglSetDrawable(aglContext, NULL);
  637.     return aglReportError ();
  638. }
  639.  
  640. //-----------------------------------------------------------------------------------------------------------------------
  641.  
  642. // ResumeGL
  643.  
  644. // resumes gl to allow gl drawing
  645.  
  646. OSStatus ResumeGL (AGLDrawable aglDraw, AGLContext aglContext)
  647. {
  648.     aglSetDrawable(aglContext, aglDraw);
  649.     return aglReportError ();
  650. }
  651.